<?php
    include_once "Conexao.php";
    include_once getenv('DOCUMENT_ROOT')."/capcliente/ACTION/ACTFactory.php";
    include_once getenv('DOCUMENT_ROOT')."/capcliente/VOB/VOBFactory.php";

    /**
     * @abstract
     * @package /DAO
     * @version 1.0
     */
    abstract class ModelDAO {

        protected $conn;
        protected $instance;
        protected $objeto;

        public function ModelDAO(){
            
        }

        protected function getConexao(){
            $this->instance = Conexao::getInstancia();
            $this->conn = $this->instance->adodbConexao();
            if($this->conn->databaseType == "mssql"){
                $this->conn->SetFetchMode(ADODB_FETCH_ASSOC);
            }
        }

        public function listar($where, $order){

            $this->getConexao();
            
            $lista = null;

            $VOBf = VOBFactory::getInstancia();
            $ACTf = ACTFactory::getInstancia();
            
            $array = $this->conn->MetaColumnNames($this->objeto->getTabela());
            
            $listCol = "";
            if($array != null){
                foreach($array as $campos){
                    $listCol.= ", {$campos}";
                }
                $listCol = substr_replace($listCol,"",0,1);

                if($where != ""){$where = " WHERE ".$where." ";}
                if($order != ""){$order = " ORDER BY ".$order." ";}
                
                $sql = "SELECT {$listCol} FROM {$this->objeto->getTabela()}{$where}{$order}";
                $rs = $this->conn->Execute($sql);
    
                $this->logError($rs,'listar',$sql);

                $util = $ACTf->getUtil();

                $lista = array();
                if($rs != null){
                    foreach ($rs as $array) {
                        $lista[] = $util->copiarPropridades($array, $this->objeto);
                    }
                } else {

                }
            }
            
            return $lista;
            
        }

        /*
         * Usuario::inserir
         */
        public function inserir($objeto){

            $this->getConexao();
            $ACTf = ACTFactory::getInstancia();

            $array = $this->conn->MetaColumnNames($objeto->getTabela());
            $stmtValue = str_repeat(", ? ", count($objeto->getPersistence()) - 1);

           
            foreach ($objeto->getPersistence() as $persistence=>$tipo){
                  
                 $coluns .= ", ".array_search($persistence, $objeto->getColMap());
            }
         
            
            if(array_search("ide_usuario_criador", $array)){
                $flag = true;
                $coluns .= ", ide_usuario_criador, dat_criacao";
                $stmtValue .= ", ?, ?";
            }
            

            $coluns = substr_replace($coluns,"",0,2);
            $stmt = $this->conn->Prepare("INSERT INTO {$objeto->getTabela()} ({$coluns}) VALUES (? {$stmtValue})");
           //echo $stmt;
            $util = $ACTf->getUtil();
            $arrayValue = $util->obterPropriedades($objeto->getPersistence(), $objeto);

            if($flag){
                /**
                 * Improviso por causa da nao utilizacao do security
                 *
                 */
                $arrayValue[] = 1;
                $arrayValue[] = mktime();
            }

            $rs = $this->conn->Execute($stmt, $arrayValue);

            $this->logError($rs,'inserir',$stmt);

            $this->conn->close();

            return $rs;

        }

        public function atualizar($objeto){

            $this->getConexao();

            $ACTf = ACTFactory::getInstancia();

            $array = $this->conn->MetaColumnNames($objeto->getTabela());

            foreach ($objeto->getPersistence() as $persistence=>$tipo){
                 $coluns .= array_search($persistence, $objeto->getColMap())."=?, ";
            }
            $coluns = substr_replace($coluns,"",strlen($coluns)-2,strlen($coluns)-1);

            if(array_search("ide_usuario_atualizador", $array)){
                $flag = true;
                $coluns .= ", ide_usuario_atualizador=?, dat_atualizacao=?";
            }
            
            $id = array_search("id",$objeto->getColMap());

            $stmt = $this->conn->Prepare("UPDATE {$objeto->getTabela()} SET {$coluns} WHERE {$id} = ? ");

            $util = $ACTf->getUtil();
            $arrayValue = $util->obterPropriedades($objeto->getPersistence(), $objeto);

            /**
             * Improviso por causa da nao utilizacao do security
             *
             */
            if($flag){
                $arrayValue[] = 1;
                $arrayValue[] = mktime();
            }
            
            $arrayValue[] = $objeto->getId();
            
            $rs = $this->conn->Execute($stmt, $arrayValue);
            $this->logError($rs,'atualizar',$stmt);

            $this->conn->close();

            return $rs;
        }

        public function deletar($objeto){

            $this->getConexao();

            $ACTf = ACTFactory::getInstancia();
            $id = array_search("id",$objeto->getColMap());
            
            $stmt = $this->conn->Prepare("DELETE FROM {$objeto->getTabela()} WHERE {$id} = ?");
            $rs = $this->conn->Execute($stmt, array($objeto->getId()));
            $this->logError($rs,'deletar',$stmt);

            $this->conn->close();

            return $rs;

        }

        public function obterQuantidade($where){
            
            $this->getConexao();

            $total = 0;

            if($where != ""){$where = " WHERE ".$where." ";}

            $sql = "SELECT COUNT(*) AS total FROM {$this->objeto->getTabela()}".$where."";
            
            $rs = $this->conn->Execute($sql);
            $this->logError($rs,'obterQuantidade',$sql);

            $this->conn->close();

            if($rs != null){
                foreach ($rs as $total) {
                    $total = $total['total'];
                }
            } else {
                throw new Exception("Falha ao Executar a Query, Consulte o logError.");
            }
            
            return $total;

        }

        public function obterSoma($coluns, $colunSoma, $where){

            $array = null;

            $this->getConexao();

            if($where != ""){$where = " WHERE ".$where." ";}

            if($coluns != ""){
                $group = " GROUP BY ".$coluns." ";
                $s = ",";
            }

            $sql = "SELECT {$coluns}{$s} sum({$colunSoma}) AS total FROM {$this->objeto->getTabela()}{$where}{$group}";
            
            $rs = $this->conn->Execute($sql);
            $this->logError($rs,'obterSoma',$sql);
            
            $this->conn->close();

            if($rs != null){
                foreach ($rs as $y) {
                    $arrayTemp = null;
                    foreach($y as $k=>$x){
                        if(!is_integer($k)){
                            $arrayTemp[$k] = $x;
                        }
                    }
                    $array[] = $arrayTemp;
                }
            }
            return $array;
        }

        protected function logError($rs, $acao, $sql){
            if (!$rs) {
                $fp = fopen("../logError.txt", "a");
                fwrite($fp, "(".date("d-m-Y H:i:s").") EM: {$acao} {$this->objeto->getTabela()}: ");
                fwrite($fp, $this->conn->ErrorMsg()." #SQL#: [");
                fwrite($fp, $sql."]\n\n");
                fclose($fp);
            }
        }

    }
?>